/**
* Copyright (C) 2020 Xilinx, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may
* not use this file except in compliance with the License. A copy of the
* License is located at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/

#ifndef _XFCOMPRESSION_ZLIB_LZ77_COMPRESS_MM_HPP_
#define _XFCOMPRESSION_ZLIB_LZ77_COMPRESS_MM_HPP_

/**
 * @file zlib_lz77_compress_mm.hpp
 * @brief Header for lz77 compression kernel used in zlib compression.
 *
 * This file is part of Vitis Data Compression Library.
 */

#include "hls_stream.h"
#include "lz_compress.hpp"
#include "lz_optional.hpp"
#include "mm2s.hpp"
#include "s2mm.hpp"
#include "stream_downsizer.hpp"
#include "stream_upsizer.hpp"
#include "zlib_specs.hpp"

#include <ap_int.h>
#include <assert.h>
#include <stdint.h>
#include <stdio.h>

#define GMEM_DWIDTH 512
#define GMEM_BURST_SIZE 16

// LZ specific Defines
#define LZ_MAX_OFFSET_LIMIT 32768
#define MAX_MATCH_LEN 255
#define MATCH_LEN 6
#define MATCH_LEVEL 6
#define DICT_ELE_WIDTH (MATCH_LEN * 8 + 24)
#define OUT_BYTES (4)
#define MIN_MATCH 3

extern "C" {
/**
 * @brief LZ77 compression kernel takes the raw data as input and compresses the
 * data in block based fashion and writes the output to global memory. LZ77 is a
 * byte based compression scheme. The resulting output from this kernel is
 * represented in packet form of 32bit length <Literal, Match Length, Distance>.
 * It also generates output of literal and distance frequencies for dynamic
 * huffman tree generation. The output generated by this kernel is referred by
 * TreeGen and Huffman Kernels.
 *
 * @param in input stream
 * @param out output stream
 * @param compressd_size compressed output size of each block
 * @param in_block_size input block size of each block
 * @param dyn_ltree_freq literal frequency data
 * @param dyn_dtree_freq distance frequency data
 * @param block_size_in_kb input block size in bytes
 * @param input_size input data size
 *
 */
void xilLz77Compress(const xf::compression::uintMemWidth_t* in,
                     xf::compression::uintMemWidth_t* out,
                     uint32_t* compressd_size,
                     uint32_t* in_block_size,
                     uint32_t* dyn_ltree_freq,
                     uint32_t* dyn_dtree_freq,
                     uint32_t block_size_in_kb,
                     uint32_t input_size);
}

#endif // _XFCOMPRESSION_ZLIB_LZ77_COMPRESS_MM_HPP_
